from typing import List,Dict,Tuple
import SqliteHelper as sqlhp
from enums import OptionEnums,DRGTypeEnums
from grouperdb import GrouperDB
from dataclass import MedicalRecord
from drg_group.chs_drg_11.Base import GroupResult


class DRGCaculator:
    # group_result:GroupResult=None
    # medical_record=None
    drgs_code:str=''
    drgs_name:str=''
    drgs_weights:float=0.0                                     #病组权重（基础点数）
    drgs_ratio:float=0.0                                       #等级系数
    drgs_average:float=0.0                                     #病组例均费用
    drg_type:str=''                                            #病组类型,住院超61天、低倍率病例……
    main_average:float=OptionEnums.MAIN_AVERAGE.value          # 统筹区域例均费用
    resident_price:float=OptionEnums.RESIDENT_PRICE.value      # 居民医保点值
    employees_price:float=OptionEnums.EMPLOYEES_PRICE.value     # 职工医保点值
    patient_weights:float=0.0                                  # 病例权重（病例点数）
    drg_amount:Dict={'resident':0.0,'employees':0.0}            # drg病例费用，含自费部分
    patient_amount:float=0.0                                   # 病例总费用

    def __init__(self, group_result:GroupResult, medical_record:MedicalRecord):
        self.group_result=group_result
        self.medical_record=medical_record
        self.patient_amount=float(self.medical_record.patient_amount)
        
    def get_drgs_info(self):
        drgs=GrouperDB().query_drgs_one(self.group_result.drg)
        if not drgs:
            return None
        self.drgs_code=drgs['CODE']
        self.drgs_name=drgs['NAME']
        self.drgs_weights=drgs['WEIGHTS']
        self.drgs_ratio=drgs['RATIO']
        self.drgs_average=drgs['AVERAGE']


    def is_higher(self)->Tuple[bool,float]:
        if self.medical_record.patient_amount<=self.drgs_average*1.3:
            return (False,0)
        
        if self.drgs_weights<=100:
            if self.medical_record.patient_amount>self.drgs_average*2.5:
                return (True,2.5)
            else:
                return (False,0)            
        
        elif self.drgs_weights<=200:
            if self.medical_record.patient_amount>self.drgs_average*2:
                return (True,2)
            else:
                return (False,0)
            
        elif self.drgs_weights<=500:
            if self.medical_record.patient_amount>self.drgs_average*1.5:
                return (True,1.5)
            else:
                return (False,0)
            
        else:
            if self.medical_record.patient_amount>self.drgs_average*1.3:
                return (True,1.3)
        return (False,0)

    def is_lower(self)->bool:
         if self.medical_record.patient_amount<self.drgs_average*0.4:
                return True
         return False


    def calculate_drg_amount(self):        
        if int(self.medical_record.days)>=61:
            self.patient_weights=round(self.medical_record.patient_amount/self.main_average*100,2)
            self.drg_type=DRGTypeEnums.GREETER_THAN_60.value
        else:
            is_higher,multiplier =self.is_higher()
            if is_higher:
                self.patient_weights=self.drgs_weights*self.drgs_ratio+(self.medical_record.patient_amount/self.drgs_average-multiplier)*self.drgs_weights
                self.drg_type=DRGTypeEnums.HIGHER_MULTIPLIER.value
            elif self.is_lower():
                self.patient_weights=self.medical_record.patient_amount/self.drgs_average*self.drgs_weights*self.drgs_ratio
                self.patient_weights=min(self.patient_weights,self.drgs_weights*self.drgs_ratio*0.4)
                self.drg_type=DRGTypeEnums.LOWER_MULTIPLIER.value
            else:
                if self.medical_record.leaving_type==2 or self.medical_record.leaving_type==4 or self.medical_record.leaving_type==5 or self.medical_record.leaving_type==9:
                    self.patient_weights=self.drgs_weights*self.drgs_ratio*(self.medical_record.patient_amount/self.drgs_average)
                    self.drg_type=DRGTypeEnums.INCOMPLETE_INPATIENT.value
                else:
                    self.patient_weights=self.drgs_weights*self.drgs_ratio
                    self.drg_type=DRGTypeEnums.NORMAL_INPATIENT.value

        self.drg_amount['resident']=int(self.patient_weights*self.resident_price)
        self.drg_amount['employees']=int(self.patient_weights*self.employees_price)
        self.patient_weights=round(self.patient_weights,2)
    
    def drg_computed(self):
        self.get_drgs_info()
        if not self.drgs_code:
            return None        
        self.calculate_drg_amount()
        return self


    # def to_drg_record(self)->DRGRecord:

    #     return DRGRecord(
    #         drgs_code=self.drgs_code,
    #         drgs_name=self.drgs_name,
    #         drgs_weights=self.drgs_weights,
    #         drgs_ratio=self.drgs_ratio,
    #         drgs_average=self.drgs_average,
    #         drg_type=self.drg_type,
    #         main_average=self.main_average,
    #         resident_price=self.resident_price,
    #         employees_price=self.employees_price,
    #         patient_weights=self.patient_weights,
    #         drg_amount=self.drg_amount,
    #         # medical_record=self.medical_record
    #     )
